/**
 * 
 */
package org.opencare.plugins.model;

import java.io.IOException;
import java.io.StringReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * @author nontster
 * 
 */
public class MessageBuilderImpl implements MessageBuilder {
	protected final Log logger = LogFactory.getLog(getClass());


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.opencare.listener.RSSBuilder#build(java.lang.String)
	 */
	public List<MessageObject> build(String xmlSource) {
		// TODO Auto-generated method stub
		
		List<MessageObject> msgList = new ArrayList<MessageObject>(); 
		
		logger.debug("Parsing EDXL.......");

		try {
			
			DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			Document document = builder.parse(new InputSource(new StringReader(xmlSource)));

			
			XPath xpath = XPathFactory.newInstance().newXPath();
			String expression = "EDXLDistribution/contentObject/*";

			// First, obtain the element as a node.
			NodeList nodes = (NodeList) xpath.evaluate(expression, document,
					XPathConstants.NODESET);

			for (int i = 0; i < nodes.getLength(); i++) {
				Node n = nodes.item(i);
				if (n.getNodeName().equalsIgnoreCase("xmlContent")) {
					NodeList childNodes = n.getChildNodes();

					for (int j = 0; j < childNodes.getLength(); j++) {
						Node m = childNodes.item(j);
						if (m.getNodeName().equalsIgnoreCase("embeddedXMLContent")) {
							NodeList cap = m.getChildNodes();
							
							for (int z = 0; z < cap.getLength(); z++) {
								
								if (cap.item(z).getNodeName().equalsIgnoreCase("alert")) {

									logger.debug("<alert> element found....");
									MessageObject messageObj = new MessageObject();
									NodeList gdacsChildNodes = cap.item(z).getChildNodes();

									for (int k = 0; k < gdacsChildNodes.getLength(); k++) {
										
										Node chNode = gdacsChildNodes.item(k);

										if (chNode.getNodeName().equalsIgnoreCase("sent")) {

											SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ",Locale.US);

											try {
												String[] pubString = chNode.getTextContent().split(":");

												StringBuffer buff = new StringBuffer();
												buff.append(pubString[0])
													.append(":")
													.append(pubString[1])
													.append(":")
													.append(pubString[2])
													.append(pubString[3]);

												Date pubDate = dateFormat.parse(buff.toString());
												messageObj.setPubDate(pubDate);

											} catch (DOMException e) {
												e.printStackTrace();
											} catch (ParseException e) {
												e.printStackTrace();
											}
										} else if (chNode.getNodeName().equalsIgnoreCase("identifier")) {
											messageObj.setIdentifier(chNode.getTextContent());							
										} else if (chNode.getNodeName().equalsIgnoreCase("sender")) {
											messageObj.setSender(chNode.getTextContent());							
										} else if (chNode.getNodeName().equalsIgnoreCase("status")){
											messageObj.setMessageType(chNode.getTextContent());	
										}else if (chNode.getNodeName().equalsIgnoreCase("info")) {

											NodeList infoChildNodes = chNode.getChildNodes();

											for (int b = 0; b < infoChildNodes.getLength(); b++) {

												Node infoChNode = infoChildNodes.item(b);

												if (infoChNode.getNodeName().equalsIgnoreCase("headline")) {						
													messageObj.setHeadline(infoChNode.getTextContent());
												} else if (infoChNode.getNodeName().equalsIgnoreCase("description")) {
													messageObj.setDescription(infoChNode.getTextContent());
												} else if(infoChNode.getNodeName().equalsIgnoreCase("web")){
													messageObj.setMapPath(infoChNode.getTextContent());
												} else if (infoChNode.getNodeName().equalsIgnoreCase("category")) {
													messageObj.setCategory(infoChNode.getTextContent());
												} else if (infoChNode.getNodeName().equalsIgnoreCase("event")) {
													messageObj.setEvent(infoChNode.getTextContent());
												} else if (infoChNode.getNodeName().equalsIgnoreCase("urgency")) {
													messageObj.setUrgency(infoChNode.getTextContent());
												} else if (infoChNode.getNodeName().equalsIgnoreCase("certainty")) {
													messageObj.setCertainty(infoChNode.getTextContent());
												} else if (infoChNode.getNodeName().equalsIgnoreCase("severity")) {
													messageObj.setSeverity(infoChNode.getTextContent());
												} else if (infoChNode.getNodeName().equalsIgnoreCase("language")) {
													messageObj.setLanguage(infoChNode.getTextContent());
												} else if (infoChNode.getNodeName().equalsIgnoreCase("resource")) {
													
													NodeList resourceNode = infoChNode.getChildNodes();

													String uri = null;
													for (int a = 0; a < resourceNode.getLength(); a++) {
														Node resourceChNode = resourceNode.item(a);

														if (resourceChNode.getNodeName().equalsIgnoreCase("uri")) {
															uri = resourceChNode.getTextContent();
															messageObj.setMapPath(resourceChNode.getTextContent());
														}
													}
												} else if (infoChNode.getNodeName().equalsIgnoreCase("parameter")) {
													logger.debug("param node!");
													
													NodeList paramNodeList = infoChNode.getChildNodes();
													
													for (int pn = 0; pn < paramNodeList.getLength(); pn++) {
														Node paramNode = paramNodeList.item(pn);
																									
														if(paramNode.getTextContent().equalsIgnoreCase("alertLevel")){
															Node nextParam = paramNodeList.item(pn+1);
															logger.debug(nextParam.getTextContent());													
															messageObj.setAlertLevel(nextParam.getTextContent());
														}
													}
													
												}
											}
										} // end info nodes
									} // end child of alerts
				
									msgList.add(messageObj);

								} // end alerts
							}
						}
					}

				} else if (n.getNodeName().equalsIgnoreCase("nonXMLContent")) {

				}
			}

		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (XPathExpressionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return msgList;
	}
}
